package tt.dz.biz.service.task;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import tt.dz.biz.annotation.MsLog;
import tt.dz.biz.dao.common.CommonDAO;
import tt.dz.biz.dao.merch.ChangeDayDAOImp;
import tt.dz.biz.dao.merch.MerchAccountDetailDAOImp;
import tt.dz.biz.service.Job.JobLockService;
import tt.dz.common.BusinessException;
import tt.dz.common.DzConstants;
import tt.dz.common.DzConstants.BizType;
import tt.dz.common.DzConstants.SysState;
import tt.dz.common.DzConstants.bizSysCode;
import tt.dz.common.DzConstants.jobStatus;
import tt.dz.common.DzConstants.sysJob;
import tt.dz.common.LogUtil;
import tt.dz.vo.ChangeDayVO;
import tt.dz.vo.JobLockVO;

@Service("dailyAccountTask")
public class DailyAccountTaskService
  extends DailyTaskService
{
  @Resource(name="changeDayDAO")
  ChangeDayDAOImp changeDayDAOImp;
  @Resource(name="merchAccountDetailDAO")
  MerchAccountDetailDAOImp merchAccountDetailDAO;
  @Resource(name="commonDAO")
  CommonDAO commonDAO;
  @Resource(name="jobLockService")
  protected JobLockService jobLockService;
  
  @MsLog(bizCode="dailyAccountTask", bizName="日记账任务", bizType=DzConstants.BizType.JOB, bizDesc="此任务只包含日记账")
  public void execute()
    throws Exception
  {
    try
    {
      beforeExecuteTask();
      DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
      long startTime = System.currentTimeMillis();
      LogUtil.info("日记账任务执行开始……");
      ChangeDayVO changeDay = this.changeDayDAOImp.queryChangeDay();
      Date accountingDate = changeDay.getYtdAccountingDate();
      int n = this.merchAccountDetailDAO.queryCountDetailTotalForDay(accountingDate);
      if (n > 0)
      {
        int c = this.merchAccountDetailDAO.deleteAccountDetailForDay(accountingDate);
        if (n != c) {
          throw new BusinessException("【" + df.format(accountingDate) + "】已存在已有明细账条数和删除条数不等，避免产生重复或错误数据，不执行日记账任务。");
        }
      }
      this.merchAccountDetailDAO.accountDividendToDetail(accountingDate);
      afterExecuteTask();
      long endTime = System.currentTimeMillis();
      LogUtil.info("【" + df.format(accountingDate) + "】日记账任务执行结束……耗时" + (endTime - startTime) + "毫秒");
    }
    catch (Exception e)
    {
      LogUtil.error("日记账任务异常，jobvo为：" + this.jobvo, e);
      throw e;
    }
  }
  
  protected void beforeExecuteTask()
    throws Exception
  {
    this.jobvo = this.jobLockService.updateJobStatusForLock(DzConstants.sysJob.DAILY_ACCOUNT_TASK.value());
    if (null == this.jobvo) {
      throw new BusinessException("锁日记账任务（" + DzConstants.sysJob.DAILY_ACCOUNT_TASK.value() + "）失败，不能执行！！！");
    }
    String stateCode = this.commonDAO.getCurrentSysState(DzConstants.bizSysCode.MAIN_SERVER.value());
    if (!this.jobvo.getStateCode().equals(stateCode)) {
      throw new BusinessException("系统状态为" + stateCode + "与运行日记账任务需要的状态" + DzConstants.SysState.DAY_CHANGED.value() + "不一致，不能执行日记账任务。");
    }
  }
  
  protected void afterExecuteTask()
    throws Exception
  {
    this.jobvo.setStatus(DzConstants.jobStatus.WAITING.value());
    this.jobLockService.updateJobStatusForRestart(this.jobvo);
    try
    {
      this.jobLockService.updateLastRunTimeByCode(this.jobvo.getJobCode());
      int i = this.commonDAO.updateSysCurrentState(DzConstants.SysState.DAILY_ACCOUNTED.value());
      if (i < 1) {
        throw new Exception("日记账任务（dailyAccountTask）后更新系统当前状态失败！");
      }
    }
    catch (Exception e)
    {
      LogUtil.error("日记账任务完成处理异常，jobcode为：" + this.jobvo.getJobCode(), e);
      throw e;
    }
  }
}
